#include "srt/srt.h"
#include "srt_server.h"
#include "common/common.h"
#include "pico/mutex.h"
#include <string.h>


struct TSrtBoolItemTag
{
    Bool   is_set;     ///< 是否设置过
    UInt32 timestamp;  ///< 设置时间戳
    Bool   value;      ///< 属性值
};
typedef struct TSrtBoolItemTag TSrtBoolItem;

struct TSrtFloatItemTag
{
    Bool   is_set;     ///< 是否设置过
    UInt32 timestamp;  ///< 设置时间戳
    Float  value;      ///< 属性值
};
typedef struct TSrtFloatItemTag TSrtFloatItem;

static Bool    is_init_ = False;  ///< 是否初始化

static mutex_t lock_arr_[kSrtPidTypeMax];           ///< 锁

static TSrtBoolItem srt_bool_arr_[kSrtBoolMax];     ///< Bool属性表

static TSrtFloatItem srt_float_arr_[kSrtFloatMax];  ///< Float属性表

/**
 * 属性初始化
 *
 */
void TSrtInit(void)
{
    for (Int32 idx = 0; idx < kSrtPidTypeMax; idx ++)
    {
        mutex_init(&lock_arr_[idx]);
    }

    memset(srt_bool_arr_, 0x00, sizeof(srt_bool_arr_));
    memset(srt_float_arr_, 0x00, sizeof(srt_float_arr_));

    is_init_ = True;
}

/**
 * 属性去初始化
 *
 */
void TSrtFini(void)
{
    is_init_ = False;
}


/**
 * 获取属性是否被设置过
 *
 * @param pid_type 属性类型
 * @param pid 属性ID，详见 TSrtPidBool
 * @return Bool 是否设置过
 */
Bool TSrtIsSet(TSrtPidType pid_type, Int32 pid)
{
    Bool ret = False;

    if (is_init_)
    {
        switch (pid_type)
        {
        case kSrtPidTypeBool:   ///< Bool  属性
        {
            if (pid < kSrtBoolMax)
            {
                mutex_enter_blocking(&lock_arr_[kSrtPidTypeBool]);
                ret = srt_bool_arr_[pid].is_set;
                mutex_exit(&lock_arr_[kSrtPidTypeBool]);
            }
        }
            break;
        case kSrtPidTypeFloat:  ///< Float 属性
        {
            if (pid < kSrtFloatMax)
            {
                mutex_enter_blocking(&lock_arr_[kSrtPidTypeFloat]);
                ret = srt_float_arr_[pid].is_set;
                mutex_exit(&lock_arr_[kSrtPidTypeFloat]);
            }
        }
            break;

        default:
            break;
        }
    }

    return ret;
}

/**
 * 获取属性时间戳
 *
 * @param pid_type 属性类型
 * @param pid 属性ID，详见 TSrtPidBool
 * @param timestamp 输出缓冲区
 * @return Bool 获取结果
 */
Bool TSrtGetTimestamp(TSrtPidType pid_type, Int32 pid, UInt32 *timestamp)
{
    Bool ret = False;

    if (is_init_)
    {
        switch (pid_type)
        {
        case kSrtPidTypeBool:   ///< Bool  属性
        {
            if (pid < kSrtBoolMax)
            {
                mutex_enter_blocking(&lock_arr_[kSrtPidTypeBool]);
                memcpy(timestamp, &srt_bool_arr_[pid].timestamp, sizeof(srt_bool_arr_[pid].timestamp));
                mutex_exit(&lock_arr_[kSrtPidTypeBool]);
                ret = True;
            }
        }
            break;
        case kSrtPidTypeFloat:  ///< Float 属性
        {
            if (pid < kSrtFloatMax)
            {
                mutex_enter_blocking(&lock_arr_[kSrtPidTypeFloat]);
                memcpy(timestamp, &srt_float_arr_[pid].timestamp, sizeof(srt_float_arr_[pid].timestamp));
                mutex_exit(&lock_arr_[kSrtPidTypeFloat]);
                ret = True;
            }
        }
            break;

        default:
            break;
        }
    }

    return ret;
}

/**
 * 获取Bool类型属性
 *
 * @param pid 属性ID，详见 TSrtPidBool
 * @param bool_value 输出缓冲区
 * @return Bool 获取结果
 */
Bool TSrtGetBool(TSrtPidBool pid, Bool *bool_value)
{
    Bool ret = False;

    if (is_init_)
    {
        if (pid < kSrtBoolMax)
        {
            mutex_enter_blocking(&lock_arr_[kSrtPidTypeBool]);
            if (srt_bool_arr_[pid].is_set)
            {
                *bool_value = srt_bool_arr_[pid].value;
                ret = True;
            }
            mutex_exit(&lock_arr_[kSrtPidTypeBool]);
        }
    }

    return ret;
}

/**
 * 设置Bool类型属性
 *
 * @param pid 属性ID，详见 TSrtPidBool
 * @param bool_value 设置参数值
 * @return Bool 设置结果
 */
Bool TSrtSetBool(TSrtPidBool pid, Bool bool_value)
{
    Bool ret = False;

    if (is_init_)
    {
        if (pid < kSrtBoolMax)
        {
            mutex_enter_blocking(&lock_arr_[kSrtPidTypeBool]);
            srt_bool_arr_[pid].value  = bool_value;
            srt_bool_arr_[pid].is_set = True;
            mutex_exit(&lock_arr_[kSrtPidTypeBool]);
            ret = True;
        }
    }

    return ret;
}

/**
 * 获取Float类型属性
 *
 * @param pid 属性ID，详见 TSrtPidFloat
 * @param float_value 输出缓冲区
 * @return Bool 获取结果
 */
Bool TSrtGetFloat(TSrtPidFloat pid, Float *float_value)
{
    Bool ret = False;

    if (is_init_)
    {
        if (pid < kSrtFloatMax)
        {
            mutex_enter_blocking(&lock_arr_[kSrtPidTypeFloat]);
            if (srt_float_arr_[pid].is_set)
            {
                *float_value = srt_float_arr_[pid].value;
                ret = True;
            }
            mutex_exit(&lock_arr_[kSrtPidTypeFloat]);
        }
    }

    return ret;
}

/**
 * 设置Float类型属性
 *
 * @param pid 属性ID，详见 TSrtPidFloat
 * @param float_value 设置参数值
 * @return Bool 设置结果
 */
Bool TSrtSetFloat(TSrtPidFloat pid, Float float_value)
{
    Bool ret = False;

    if (is_init_)
    {
        if (pid < kSrtFloatMax)
        {
            mutex_enter_blocking(&lock_arr_[kSrtPidTypeFloat]);
            srt_float_arr_[pid].value  = float_value;
            srt_float_arr_[pid].is_set = True;
            mutex_exit(&lock_arr_[kSrtPidTypeFloat]);
            ret = True;
        }
    }

    return ret;
}
